using QFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface ISelectItemSystem : ISystem
{
    void SingleSelection();
    void AddSelectables(List<ISelectable> selectables);
    void AddSelectable(ISelectable selectables);
}
public class SelectItemSystem : AbstractSystem, ISelectItemSystem
{
    private List<ISelectable> canBeSelectedCharacters = new();
    private List<ISelectable> detectedCharacter = new();
    private List<ISelectable> toBeSelectedCharacter = new();

    private RaycastHit[] hitInfo;

    private ISelectable m_LastSelected;
    public void SingleSelection()
    {
        if (Camera.main == null || Camera.main.enabled == false) return;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (RaycastHitEx.RaycastNonAlloc(ray, hitInfo, 100))
        {
            for (int i = 0; i < hitInfo.Length; i++)
            {
                Debug.Log($"hitInfo.collider = {hitInfo[i].collider}");
            }
            ISelectable t_Selected = canBeSelectedCharacters.Find(t =>
            {
                if (t.Collider.gameObject == hitInfo[0].collider.gameObject)
                    return true;
                return false;
            });

            detectedCharacter.Clear();
            TryAddToDetected(t_Selected);

            if (t_Selected != null)
            {
                GetSingleSelection(t_Selected);
            }
        }
        else
        {
            foreach (var obj in toBeSelectedCharacter)
            {
                Desselecting(obj);
            }
            toBeSelectedCharacter.Clear();
            /*if(m_LastSelected != null)
            {
                Desselecting(m_LastSelected);
            }*/
            m_LastSelected = null;
        }
    }
    private void GetSingleSelection(ISelectable t_Selected)
    {
        foreach (var selectable in toBeSelectedCharacter)
        {
            Desselecting(selectable);
        }

        toBeSelectedCharacter = new List<ISelectable>(detectedCharacter);
        if (t_Selected == null)
            return;
        Selecting(t_Selected);

        m_LastSelected = t_Selected;
    }

    private void Selecting(ISelectable selectable)
    {
        selectable.OnSelected?.Invoke();
    }

    private void Desselecting(ISelectable selectable)
    {
        selectable.OnDeselected?.Invoke();
    }

    private void TryAddToDetected(ISelectable selectable)
    {
        if (selectable == null)
            return;
        if (detectedCharacter.Contains(selectable))
            return;
        detectedCharacter.Add(selectable);
    }

    public void AddSelectables(List<ISelectable> selectables)
    {
        canBeSelectedCharacters.AddRange(selectables);
    }
    public void AddSelectable(ISelectable selectables)
    {
        canBeSelectedCharacters.Add(selectables);
    }

    protected override void OnInit()
    {
        hitInfo = new RaycastHit[1];
    }
}
